//
//  NetWorkTools.swift
//  CXSwiftWB
//
//  Created by meidaeriOS on 2017/6/5.
//  Copyright © 2017年 meidaer. All rights reserved.
//

import UIKit
import Alamofire

class NetWorkTools: NSObject {
    
    static let baseStr = "http://application.wootop.cn:9080/wootop-api"
    
    class func postRequest(_ urlString: String?, params: [String: Any]?, success: @escaping (_ value: Any)->(), error:@escaping (_ error: Error) -> ()) {
        let totalStr = baseStr + (urlString ?? "")
        let url = URL(string: totalStr)
        
        let data = try? JSONSerialization.data(withJSONObject: params!, options: .prettyPrinted)
        let paramStr = String(data: data!, encoding: .utf8)
        
        let str = encryptUseDes(paramStr!, key: "48b1cb6869d341529d1ab12273d50ef2")!
        
        let paramDic = ["sign": str]
        
        SessionManager.default.session.configuration.timeoutIntervalForRequest = 0.05;
        let request = Alamofire.request(url!,
            method: .post,
            parameters: paramDic)
        request.responseJSON(completionHandler: { (result) in
            print(result.timeline)
            if let valueJson = result.result.value {
                success(valueJson)
            }
            
            if let errorValue = result.result.error {
                error(errorValue)
            }
        })
    }
    
    /// 上传图片
    class func imagePost(_ urlString: String?, image: UIImage?, imageCompressScale: CGFloat, success: @escaping (_ value: Any)->(), error:@escaping (_ error: Error) -> ()) {
        
        
        let totalStr = baseStr + (urlString ?? "")
        let url = URL(string: totalStr)
        
        Alamofire.upload(
            multipartFormData: { multipartFormData in
                let dateFormatter = DateFormatter()
                dateFormatter.dateFormat = "yyyyMMddHHmmss"
                let dateStr = dateFormatter.string(from: Date())
                let fileStr = "\(dateStr).jpg"
                let imageDate = UIImageJPEGRepresentation(image!, imageCompressScale)
                multipartFormData.append(imageDate!, withName: "file", fileName: fileStr, mimeType: "image/jpeg")
        },
            to: totalStr,
            encodingCompletion: { encodingResult in
                switch encodingResult {
                case .success(let upload, _, _):
                    upload.responseJSON { response in
                        if let value = response.value {
                            success(response.value!)
                        }
                        
                        if let errorValue = response.result.error {
                            error(errorValue)
                        }
                    }
                case .failure(let encodingError): break
                }
        }
        )
        
        
//        Alamofire.upload(.POST, URL, multipartFormData: {
//            multipartFormData in
//            
//            if let _image = image {
//                if let imageData = UIImageJPEGRepresentation(_image, 0.5) {
//                    multipartFormData.appendBodyPart(data: imageData, name: "file", fileName: "file.png", mimeType: "image/png")
//                }
//            }
//            
//            for (key, value) in parameters {
//                multipartFormData.appendBodyPart(data: value.dataUsingEncoding(NSUTF8StringEncoding)!, name: key)
//            }
//            
//        }, encodingCompletion: {
//            encodingResult in
//            
//            switch encodingResult {
//            case .Success(let upload, _, _):
//                upload.responseObject { (response: Response<UploadData, NSError>) -> Void in
//                    
//                    switch response.result {
//                    case .Success:
//                        completionHandler?(success: true)
//                    case .Failure(let error):
//                        completionHandler?(success: false)
//                    }
//                    
//                }
//            case .Failure(let encodingError):
//                print(encodingError)
//            }
//        })
//        
//        let data = try? JSONSerialization.data(withJSONObject: params!, options: .prettyPrinted)
//        let paramStr = String(data: data!, encoding: .utf8)
//        
//        let str = encryptUseDes(paramStr!, key: "48b1cb6869d341529d1ab12273d50ef2")!
//        
//        let paramDic = ["sign": str]
//        
//        let request = Alamofire.request(url!,
//                                        method: .post,
//                                        parameters: paramDic)
//        
//        request.responseJSON(completionHandler: { (result) in
//            if let valueJson = result.result.value {
//                success(valueJson)
//            }
//            
//            if let errorValue = result.result.error {
//                error(errorValue)
//            }
//        })
    }
    
    /// 从网上弄下来的加解密
    internal func cryptoOperation() -> String {
        // Validation checks.
        let jm = "fjdkasljfkls"
        let jmData = jm.data(using: String.Encoding.utf8)!
        let key = "\n\u{0014}\u{001E}(2<FP" //这里是java端对应的key byte[]的字符串表现形式 btye[] key = {10, 20, 30, 40, 50, 60 ,70, 80}
        var t:   String = ""
        
        // Prepare data parameters
        let keyData: Data! = key.data(using: String.Encoding.utf8, allowLossyConversion: false)!
        let keyBytes = keyData.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> UnsafePointer<UInt8> in
            return bytes
        }
        
        //let keyBytes         = keyData.bytes.bindMemory(to: Void.self, capacity: keyData.count)
        let dataLength       = Int(jmData.count)
        let dataBytes        = jmData.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> UnsafePointer<UInt8> in
            return bytes
        }
        
        
        var bufferData       = Data(count: Int(dataLength) + 8)
        let bufferPointer    = bufferData.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer<UInt8>) -> UnsafeMutablePointer<UInt8> in
            return bytes
        }
        let bufferLength     = size_t(bufferData.count)
        let ivStr = "\u{000B}\u{0016}!,7BMU" //这里是java端对应的iv变量字符串
        let iv = ivStr.data(using: String.Encoding.utf8)!
        let ivBuffer: UnsafePointer<UInt8>? = iv.withUnsafeBytes({ (bytes: UnsafePointer<UInt8>) -> UnsafePointer<UInt8> in
            return bytes
        })
        var bytesDecrypted   = Int(0)
        // Perform operation
        let cryptStatus = CCCrypt(
            0,                  // Operation 这里代表DES加密而非解密
            1,    // Algorithm 这里代表DES算法（其他数字可以是别的算法，如AES），研究一下OC的自带的方法就行了
            1,                    // Options 这里代表PKCS7Padding
            keyBytes,                   // key data
            8,                  // key length
            ivBuffer,                   // IV buffer
            dataBytes,                  // input data
            dataLength,                 // input length
            bufferPointer,              // output buffer
            bufferLength,               // output buffer length
            &bytesDecrypted)            // output bytes decrypted real length
        if Int32(cryptStatus) == Int32(kCCSuccess) {
            bufferData.count = bytesDecrypted // Adjust buffer size to real bytes
            print(bufferData)
            let a = bufferData.withUnsafeBytes{
                [UInt8](UnsafeBufferPointer(start: $0, count: bufferData.count))
            }
            print(a)
            t = bufferData.base64EncodedString()
        }
        return t
    }

    
    /// DES加密
    class func encryptUseDes(_ clearText: String, key: String) -> String? {
        var ciphertext: String?
        let textData = clearText.data(using: .utf8)
        let dataLength = textData?.count
        let bufferSize = dataLength! + kCCBlockSizeAES128
        let intPtr = UnsafeMutablePointer<size_t>.allocate(capacity: bufferSize)
        var numBytesEncrypted = 0
        
        let  dataBytes = textData?.withUnsafeBytes({ (bytes: UnsafePointer<UInt8>) -> UnsafePointer<UInt8> in
            return bytes
        })
        
        var bufferData       = Data(count: Int(dataLength!) + kCCBlockSizeAES128)
        let bufferPointer    = bufferData.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer<UInt8>) -> UnsafeMutablePointer<UInt8> in
            return bytes
        }
        let bufferLength     = size_t(bufferData.count)

        
        let keyData: Data! = key.data(using: String.Encoding.utf8, allowLossyConversion: false)!
        let keyBytes = keyData.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> UnsafePointer<UInt8> in
            return bytes
        }
        
        let cryptStatus = CCCrypt(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithmDES), CCOptions(kCCOptionPKCS7Padding | kCCOptionECBMode), keyBytes, kCCBlockSizeDES, nil, dataBytes, dataLength!, bufferPointer, bufferLength, &numBytesEncrypted)
        
        if Int32(cryptStatus) == Int32(kCCSuccess) {
//            let data = intPtr.
            bufferData.count = numBytesEncrypted // Adjust buffer size to real bytes

            ciphertext = convertDataToHexStr(bufferData)
        }
        intPtr.deallocate(capacity: bufferSize)
        return ciphertext
    }
    
    class func convertDataToHexStr(_ data: Data?) -> String {
        guard data != nil && data?.count != 0 else {
            return ""
        }
        
        var str = String()
        data?.enumerateBytes({ (bytes, cIndex : Data.Index, intout) in
            
            bytes.forEach({ (ch) in
                let tempStr = String.init(format: "%X", ch & 0xff)
                if tempStr.lengthOfBytes(using: .utf8) == 2 {
                    str.append(tempStr)
                } else {
                    str.append("0\(tempStr)")
                }
            })
        })
        return str
    }
    
    /// NSData转成16进制字符串
//    class func stringWithHexBytes2(_ sender: Data) -> String {
//        let hexDigits = "0123456789ABCDEF"
//        let  numBytes = sender.count
//        var bytes = sender.withUnsafeBytes({ (bytes: UnsafePointer<UInt8>) -> UnsafePointer<UInt8> in
//            return bytes
//        })
//        var strBuf = UnsafeMutablePointer<CChar>.allocate(capacity: numBytes * 2 + 1)
//        var hex = strBuf
//        
//        var hexBytes: String?
//        
//        for _ in 0..<numBytes {
//            let c = bytes
//            bytes += 1
//            hex = hexDigits[(c >> 4) & 0xF]
//            hex += 1
//            hex = hexDigits[(c) & 0xF]
//            hex += 1
//        }
//        
//        hex = 0
//        
//        hexBytes = String.cString(strBuf)
//        
//        strBuf.deallocate(capacity: numBytes * 2 + 1)
//        
//        return hexBytes!
//    }
}
